/**
 * GenericExtractor
 **/
jsx3.Class.defineClass(
    "ux.cdb.admin.dataautomate.GenericUpdater",
    jsx3.gui.Block,
    [ux.cdb.admin.dataautomate.IDataConsumer,ux.cdb.admin.dataautomate.IDataExtractor],
    function (block) {
        
        block.prototype.init = function(strName, vntLeft, vntTop, vntWidth, vntHeight, strHTML) {
            //call constructor for super class (the super expects the name of the object and the function that it is an instance of)
            this.jsxsuper(strName, vntLeft, vntTop, vntWidth, vntHeight, strHTML);
        };

        block.prototype.onSetParent = function(parent) {
            var ret = this.jsxsuper(parent);
            var me = this;
            setTimeout(function() {
                me.registerConsumer();
                me.registerExtractor();
            },0);

            this.setTriggerEvent();
            
            return ret;
        };

        block.prototype.onAfterAttach = function() {
            this.reArrangeUI();
            this.jsxsuper();
        };

        block.prototype.isRequired = function() {
            var validatorStr = "," + this.getValidator() + ",";
            return (validatorStr.indexOf(",Required,")>-1);
        };

        block.prototype.getLabelName = function() {
            if(this.get("lblName")) {
                return this.get("lblName").getText();
            }
            return "";
        };

        block.prototype.reArrangeUI = function() {
            
            var server = ux.megatron.Main.getServer();
            var validatorStr = "," + this.getValidator() + ",";
            if(validatorStr.indexOf(",Amount,")>-1) {
                if(this.get("yuanBlock")) return;
                var yuan = new jsx3.gui.Block("yuanBlock", 0 ,0 , "18", "");
                yuan.setCSSOverride(server.getDynamicProperty("@cdb@Unit Yuan Css Overide")).
                    setText(server.getDynamicProperty("@cdb@Unit Yuan"));
                this.setChild(yuan, jsx3.app.Model.PERSISTNONE);
            }
            if(validatorStr.indexOf(",Period,")>-1) {
                if(this.get("yearBlock")) return;
                var yuan = new jsx3.gui.Block("yearBlock", 0 ,0 , "18", "");
                yuan.setCSSOverride(server.getDynamicProperty("@cdb@Unit Period Css Overide")).
                    setText(server.getDynamicProperty("@cdb@Unit Year"));
                this.setChild(yuan, jsx3.app.Model.PERSISTNONE);
            }
            if(validatorStr.indexOf(",Percent,")>-1) {
                if(this.get("percentBlock")) return;
                var yuan = new jsx3.gui.Block("percentBlock", 0 ,0 , "9", "");
                yuan.setCSSOverride(server.getDynamicProperty("@cdb@Unit Percent Css Overide")).
                    setText(server.getDynamicProperty("@cdb@Unit Percent"));
                this.setChild(yuan, jsx3.app.Model.PERSISTNONE);
            }
            if(validatorStr.indexOf(",Required,")>-1) {
                if(this.get("starBlock")) return;
                var star = new jsx3.gui.Block("starBlock",0,0,"9","");
                star.setCSSOverride(server.getDynamicProperty("@cdb@Star Required Css Overide")).
                    setText(server.getDynamicProperty("@cdb@RequiredStar"));
                this.setChild(star, jsx3.app.Model.PERSISTNONE);
            }
        };

        /**
         * If you needed,you can override this method by different class type of subclass.
         * Common sense is you needn't to override it.
         */
        block.prototype.doValidate = function(){
            //if return null,means validation passed
            //else validation failed,and return a string to report the error information
            //if there's multiple validator,just return the first failed message.

            if(!this.getValidator()){ return null; } //there's no validator

            var validators = this.getValidator().split(',');
            var params = [], validatorFun = null;

            if(this.getValidatorParams()) {
                params = this.getValidatorParams().split(',');
            }
            var value = this.extractData();
            //ux.cdb.admin.Log.info('GenericUpdater:: '+ this.getName() + ' value: ' + value + ', validators:' + validators);
            
            for(var i=0;i<validators.length;i++){
                //Support Validator with Param, such as MaxLength(25), where validator is MaxLength and parameter is 25
                if(validators[i].indexOf("RegExp(") > -1) {
                    params[i] = validators[i].substring(validators[i].indexOf("RegExp(")+7, validators[i].length-1);
                    validators[i] = "RegExp";
                } else {
                    var reg = new RegExp("(.*)\\(([^\\)]*)\\)", "i");
                    if (reg.test(validators[i])) {
                        validators[i] = RegExp.$1;
                        params[i] = RegExp.$2;
                    };                    
                }

                validatorFun = this['validate'+validators[i]] || 
                    ux.megatron.util.ValidationManager.getValidator(validators[i]);
                if(!validatorFun) {
                    /* @JSC :: begin DEBUG */
                    ux.cdb.admin.Log.warn('Encounter a unspported validator: '+validators[i]+' in component: '+this.getName());
                    /* @JSC :: end */
                    continue;
                }
                //ux.cdb.admin.Log.info('Validator: '+validators[i]+' in component: '+this.getName());
                var ret = validatorFun.apply(this, [value, params[i]]);
                if(ret !== null){
                    this._validateFailedUI(true, ret);
                    //You could override ErrorMsg in your object
                    /* @JSC :: begin DEBUG */
                    ux.cdb.admin.Log.info('Validation failed: '+validators[i]+' in component: '+this.getName());
                    /* @JSC :: end */
                    return this['validateErrorMsg'+validators[i]] || ret;
                }
            }
            this._validateFailedUI(false);
            return null;
        };

        block.prototype.validateAmount = function() {
            //TBD
            return null;
        };

        block.prototype.validatePeriod = function() {
            //TBD
            return null;
        };

        block.prototype.validatePercent = function() {
            //TBD
            return null;
        };
        
        /**
         * need to be implemented in subclass
         */ 
        block.prototype._validateFailedUI = function(failed, message){
            //do some thing to represent the validation error message to UI
        };

        /**
         * need to be implemented in subclass
         */ 
        block.prototype.focusField = function() {
        };
        
        /**
         * Need to be implemented in subclass
         */
        block.prototype.setTriggerEvent = function() {

        };

    });